<?php

declare(strict_types=1);
namespace App\Model\PssModel;

use App\Model\BaseModel\BasePssModel;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Service\Qrcode\VerifyImg;
use App\Service\Sms\SendSmsCode;
use App\Service\AppService\CreateMerchant;

class BusinessUser extends BasePssModel
{
    public $table               = 'businessuser';
    public $loginToken          = 'merchantloginToken_';
    public $loginVolidTime      = 3600 * 24;
    public $rdb                 = 1;
    const sms_code              = 'sms_code_';
    const verify_code_passpwd   = 'verify_code_passpwd_';
    const redis_sms_key         = 'redis_sms_key_';
    
    /**
     * 商城登录
     * @author chenshubo
     */
    public function login(array $param = [])
    {
        if (empty($param['mobile'])) {
            return Normal::returnCode(Normal::FAIL,'账号不能为空');
        }
    
        if (empty($param['password'])) {
            return Normal::returnCode(Normal::FAIL,'密码不能为空');
        }
        
        if (empty($param['uuid'])) {
            return Normal::returnCode(Normal::FAIL,'uuid不能为空');
        }
    
        if (empty($param['code'])) {
            return Normal::returnCode(Normal::FAIL,'code不能为空');
        }
    
        if (empty($param['type'])) {
            return Normal::returnCode(Normal::FAIL,'type不能为空');
        }
    
        $res = VerifyImg::instance()->checkQrCode($param['uuid']."_".$param['type'],$param['code']);
        if( !$res) {
            return Normal::returnCode(Normal::FAIL,'图形验证码不正确');
        }
        
        //验证账号信息
        $merchant = Business::instance()->info(['account' => $param['mobile'],'password'=>md5($param['password'])]);
        if (empty($merchant)) {
            return Normal::returnCode(Normal::FAIL,'账号不存在，或者密码错误');
        }
        
        //判断账号是否被禁用
        if( $merchant['status'] == 1 ) {
            return Normal::returnCode(Normal::FAIL,"当前登录帐号被禁用，请联系管理员开通");
        }
    
        //生成用户TOKEN
        $time = time() + $this->loginVolidTime;
        $tokenArr = [
            'bid'       => $merchant['id'],
            'account'   => $merchant['account'],
            'password'  => $merchant['password'],
            'expire'    => $time,
        ];
        
        if(!extension_loaded('redis')) {
            return Normal::returnCode(Normal::FAIL,'登录失败，缺少扩展');
        }
    
        $signKey = implode("_", $tokenArr);
        $cacheStr = sha1(md5($signKey));
        $redis = BaseService::instance()->getRedisObj();
        $redis->select($this->rdb);
        $redis->setex($this->loginToken.$cacheStr,$this->loginVolidTime,$signKey);
        $server = request()->getServerParams();
        $data = [
            'login_time' => time(),
            'login_ip'  => $server['remote_addr']??'',
        ];
        $where = ['id' => $tokenArr['bid']];
        Business::where($where)->update($data);
        return Normal::returnCode(Normal::SUC,'登录成功',['token'=>$cacheStr,'account'=>$tokenArr['account']]);
    }
    
    /**
     * 清除缓存
     * @param string $token
     */
    public function clearCache( $token ) {
        $redis = BaseService::instance()->getRedisObj();
        $redis->del($this->loginToken.$token);
        return Normal::returnCode(Normal::SUC,'操作成功');
    }
    
    /**
     * 用户注册
     * @param array $param
     */
    public function userRegister( $param = [] )
    {
        if(empty($param['mobile'])) {
            return Normal::returnCode(Normal::FAIL,"手机号码不能为空");
        }
    
        if(empty($param['code'])) {
            return Normal::returnCode(Normal::FAIL,"图形验证码不能为空");
        }
    
        if(empty($param['smscode'])) {
            return Normal::returnCode(Normal::FAIL,"短信验证码不能为空");
        }
    
        if(empty($param['password'])) {
            return Normal::returnCode(Normal::FAIL,"设置密码不能为空");
        }
    
        if(empty($param['repassword'])) {
            return Normal::returnCode(Normal::FAIL,"确认密码不能为空");
        }
    
        if(empty($param['type'])) {
            return Normal::returnCode(Normal::FAIL,"type不能为空");
        }
    
        if(empty($param['uuid'])) {
            return Normal::returnCode(Normal::FAIL,"uuid不能为空");
        }
    
        if( !checkPhone($param['mobile']) ) {
            return Normal::returnCode(Normal::FAIL,"登录账号只能为手机号码");
        }
    
        $verify_key = $param['uuid'].'_'.$param['type'];
        $res = VerifyImg::instance()->checkQrCode($verify_key,$param['code']);
        if( !$res ) {
            return Normal::returnCode(Normal::FAIL,"图形验证码不正确，请重新输入");
        }
    
        if( $param['password'] != $param['repassword'] ) {
            return Normal::returnCode(Normal::FAIL,"设置密码和确认密码不相同，请确认之后再输入");
        }
    
        if( mb_strlen($param['password'],'utf-8') > 16 ) {
            return Normal::returnCode(Normal::FAIL,"登录密码超过位数限制");
        }
    
        if( !checkUserPassWord($param['password']) ) {
            return Normal::returnCode(Normal::FAIL,"密码输入规则需满足6-16位非空白字符 ");
        }
        
        //校验短信验证码是否正确
        $res = SendSmsCode::instance()->checkSmsCode($param);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        
        //查询商户名称是否被占用
        $merchant = Business::instance()->info([['name','=',$param['mobile']]]);
        if (!empty($merchant)) {
            return Normal::returnCode(Normal::FAIL,'手机号码已经存在');
        }
        $merchant = Business::instance()->info([['account','=',$param['mobile']]]);
        if (!empty($merchant)) {
            return Normal::returnCode(Normal::FAIL,'手机号码已经存在');
        }
        
        try {
            
            self::startTrans();
            $time = time();
            $busArr = [
                'name'              => $param['mobile'],
                'company'           => $param['mobile'],
                'linkname'          => $param['mobile'],
                'linkphone'         => $param['mobile'],
                'user_source'       => 1,
                'user_type'         => 1,
                'template_id'       => 1,
                'template_type'     => 1,
                'status'            => 0,
                'cd'                => $time,
            ];
            
            $bid = Business::instance()->add($busArr);
            if(!$bid) {
                self::rollback();
                return Normal::returnCode(Normal::FAIL,'请求失败');
            }
            
            //创建商户账号密码 appId 和
            $appId  = CreateMerchant::instance()->createAppId($bid);
            $secret = CreateMerchant::instance()->createSecret($bid,$appId);
            
            //更新密钥
            $updateData = [
                'appid'         => $appId,
                'secret'        => $secret,
                'account'       => $param['mobile'],
                'password'      => md5($param['password']),
            ];
            $res = Business::instance()->edit(['id' => $bid],$updateData);
            if(!$res) {
                self::rollback();
                return Normal::returnCode(Normal::FAIL,'写入appid和密钥失败');
            }
            
            self::commit();
            return Normal::returnCode(Normal::SUC,"注册成功，请去登录");
        } catch ( \Throwable $e) {
            self::rollback();
            return Normal::returnCode(Normal::FAIL,$e->getMessage());
        }
        
    }
    
    /**
     * 重置密码身份验证
     */
    public function verifyUser( $param = [] )
    {
        if( empty($param['mobile']) ) {
            return Normal::returnCode(Normal::FAIL,"except param mobile");
        }
    
        if( empty($param['code']) ) {
            return Normal::returnCode(Normal::FAIL,"except param code");
        }
    
        if( empty($param['uuid']) ) {
            return Normal::returnCode(Normal::FAIL,"except param uuid");
        }
    
        if( empty($param['smscode']) ) {
            return Normal::returnCode(Normal::FAIL,"except param smscode");
        }
    
        if( empty($param['type']) ) {
            return Normal::returnCode(Normal::FAIL,"except param type");
        }
    
        $mobile     = $param['mobile'];
        $uuid       = $param['uuid'];
        $smscode    = $param['smscode'];
        $code       = $param['code'];
    
        $cache_verify_code = VerifyImg::instance()->checkQrCode($uuid."_".$param['type'],$code);
        if( !$cache_verify_code ) {
            return Normal::returnCode(Normal::FAIL,"图形验证不正确");
        }
    
        $res = SendSmsCode::instance()->checkSmsCode($param);
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        
        //删除短信验证码
        sendSmsCode::instance()->delSmsCache($param);
    
        $token = md5($uuid);
        $redis = BaseService::instance()->getRedisObj();
        $redis->select(6);
        $redis->setex(self::redis_sms_key.$token,60*5,$mobile);
        return Normal::returnCode(Normal::SUC,"验证通过",[
            'sms_token' => $token
        ]);
    }
    
    /**
     * 重置密码
     */
    public function reSetPassword( $param = [] )
    {
        if( empty($param['sms_token']) ) {
            return Normal::returnCode(Normal::FAIL,"except param sms_token");
        }
    
        if( empty($param['password']) ) {
            return Normal::returnCode(Normal::FAIL,"except param password");
        }
    
        if( empty($param['repassword']) ) {
            return Normal::returnCode(Normal::FAIL,"except param repassword");
        }
    
        $redis = BaseService::instance()->getRedisObj();
        $redis->select(6);
        $cache = $redis->get(self::redis_sms_key.$param['sms_token']);
        if(!$cache) {
            return Normal::returnCode(Normal::FAIL,"当前验证已失效，请重新发送验证码");
        }
    
        $password = $param['password'];
        if( $password !== $param['repassword'] ) {
            return Normal::returnCode(Normal::FAIL,"输入密码不相等，请确认");
        }
    
        if( !checkUserPassWord($password) ) {
            return Normal::returnCode(Normal::FAIL,"密码输入规则需满足6-16位非空白字符 ");
        }
        
        Business::instance()->edit(['account' => $cache],['md' => time(),'password' => md5($password)]);
        return Normal::returnCode(Normal::SUC,"重置密码成功，请重新登录");
    }
    
    /**
     * 商户账号
     * @param string $account
     */
    public function getUserInfoByAccount( $account = NULL )
    {
        return $this->info(['account' => $account]);
    }
}